//
//  dcmtkWrap.cpp
//  DcmtkJni
//
//  Created by 夏 申频 on 14-2-10.
//  Copyright (c) 2014年 oritsh. All rights reserved.
//

#include "dcmtkWrap.h"

#include "dcmtk/dcmdata/dctk.h"
#include "dcmtk/dcmdata/cmdlnarg.h"
#include "dcmtk/ofstd/ofconapp.h"
#include "dcmtk/dcmdata/dcuid.h"       /* for dcmtk version name */
#include "dcmtk/dcmjpeg/djdecode.h"    /* for dcmjpeg decoders */
#include "dcmtk/dcmjpeg/djencode.h"    /* for dcmjpeg encoders */
#include "dcmtk/dcmjpeg/dipijpeg.h"

#include "dcmtk/dcmdata/dcistrmb.h"
#include "dcmtk/dcmdata/dcostrmb.h"

#include "dcmtk/dcmjpls/djencode.h"
#include "dcmtk/dcmjpls/djdecode.h"

#include "dcmtk/dcmjpeg/djrplol.h"

class JavaString{
private:
    JNIEnv* env;
    jstring str;
    const char* buffer;
public:
    JavaString(JNIEnv* env,jstring str){
        this->env = env;
        this->str = str;
        buffer=env->GetStringUTFChars(str,0);
    }
    ~JavaString(){
        env->ReleaseStringUTFChars( this->str, buffer);
    }
    const char* c_str(){
        return buffer;
    }
};

int decode(const char* srcfilename,const char* destfilename){
    int status = -1;
    DJDecoderRegistration::registerCodecs(); // register JPEG codecs
    DJLSDecoderRegistration::registerCodecs();
    DcmFileFormat fileformat;
    if (fileformat.loadFile(srcfilename).good())
    {
        DcmDataset *dataset = fileformat.getDataset();
        // decompress data set if compressed
        dataset->chooseRepresentation(EXS_LittleEndianExplicit, NULL);
        // check if everything went well
        if (dataset->canWriteXfer(EXS_LittleEndianExplicit))
        {
            fileformat.saveFile(destfilename, EXS_LittleEndianExplicit);
            status = 0;
        }
    }
    DJDecoderRegistration::cleanup(); // deregister JPEG codecs
    DJLSDecoderRegistration::cleanup(); // deregister JPEG-LS codecs

    return status;
}

int encode(const char* srcfilename,const char* destfilename){
    int status = -1;
    DJEncoderRegistration::registerCodecs(); // register JPEG codecs
    DcmFileFormat fileformat;
    if (fileformat.loadFile(srcfilename).good())
    {
        DcmDataset *dataset = fileformat.getDataset();
        DcmItem *metaInfo = fileformat.getMetaInfo();
        DJ_RPLossless params; // codec parameters, we use the defaults
        // this causes the lossless JPEG version of the dataset to be created
        dataset->chooseRepresentation(EXS_JPEGProcess14SV1TransferSyntax, &params);
        // check if everything went well
        if (dataset->canWriteXfer(EXS_JPEGProcess14SV1TransferSyntax))
        {
            // force the meta-header UIDs to be re-generated when storing the file
            // since the UIDs in the data set may have changed
            //delete metaInfo->remove(DCM_MediaStorageSOPClassUID);
            //delete metaInfo->remove(DCM_MediaStorageSOPInstanceUID);
            // store in lossless JPEG format
            fileformat.saveFile(destfilename, EXS_JPEGProcess14SV1TransferSyntax);
            status = 0;
        }
    }
    DJEncoderRegistration::cleanup(); // deregister JPEG codecs

    return status;
}

#ifdef __cplusplus
extern "C" {
#endif
    /*
     * Class:     com_oritsh_dicom_dcmtk_DcmtkWrap
     * Method:    imageDecode
     * Signature: (Ljava/lang/String;Ljava/lang/String;)I
     */
    JNIEXPORT jint JNICALL Java_com_oritsh_dicom_dcmtk__1_1DcmtkWrap_1_1__1_1imageDecode_1_1
    (JNIEnv * env, jclass, jstring src, jstring dest){
        jint status = -1;
        
        JavaString jsrc(env, src);
        JavaString jdest(env, dest);
        std::cout<<"Decode dicom file from "<<jsrc.c_str()<<" to "<<jdest.c_str()<<std::endl;
        status = decode(jsrc.c_str(), jdest.c_str());
        
        return status;
    }
    
    /*
     * Class:     com_oritsh_dicom_dcmtk_DcmtkWrap
     * Method:    imageEncode
     * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
     */
    JNIEXPORT jint JNICALL Java_com_oritsh_dicom_dcmtk__1_1DcmtkWrap_1_1__1_1imageEncode_1_1
    (JNIEnv * env, jclass, jstring src, jstring dest, jstring){
        jint status = -1;
        
        JavaString jsrc(env, src);
        JavaString jdest(env, dest);
        
        status = encode(jsrc.c_str(), jdest.c_str());
        
        return status;
    }
    
#ifdef __cplusplus
}
#endif
